package com.wonders.hisdoctor.station.project.hisqueue.service.impl;

import com.wonders.his.common.exception.CustomException;
import com.wonders.his.common.service.project.base.domain.AppBaseParam;
import com.wonders.his.common.service.project.base.service.IAppBaseParamService;
import com.wonders.his.common.service.utils.CountAgeUtil;
import com.wonders.his.common.utils.DateUtils;
import com.wonders.his.common.utils.StringUtils;
import com.wonders.his.framework.dto.LoginUserDTO;
import com.wonders.his.framework.service.TokenService;
import com.wonders.hisdoctor.station.constant.ServiceConstant;
import com.wonders.hisdoctor.station.enums.AppBaseParamEnum;
import com.wonders.hisdoctor.station.project.base.domain.OutpWaitQueue;
import com.wonders.hisdoctor.station.project.hisqueue.mapper.HisQueueMapper;
import com.wonders.hisdoctor.station.project.hisqueue.service.IQueueService;
import com.wonders.hisdoctor.station.project.hisqueue.vo.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 就诊队列service实现
 *
 * @author zhanghaonan
 * @date 2021/01/20
 */
@Service
public class QueueServiceImpl implements IQueueService {

    @Autowired
    private HisQueueMapper hisQueueMapper;

    @Autowired
    private IAppBaseParamService appBaseParamService;

    @Autowired
    private TokenService tokenService;

    @Override
    public PatientInfoResponseVo selectPatientInfo(PatientInfoRequestVo requestVo) {
        //查询密级过滤数组
        AppBaseParam appBaseParam = new AppBaseParam();
        appBaseParam.setKeyName(AppBaseParamEnum.SECRET_LEVEL.getCode());
        List<AppBaseParam> appBaseParams = appBaseParamService.selectList(appBaseParam);
        if (!CollectionUtils.isEmpty(appBaseParams)) {
            List<String> list = appBaseParams.stream().map(AppBaseParam::getValueName).collect(Collectors.toList());
            requestVo.setSecretLevelList(list);
        }
        PatientInfoResponseVo patientInfoResponseVo = hisQueueMapper.selectPatientInfo(requestVo);
        if (patientInfoResponseVo != null) {
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DateUtils.YYYY_MM_DD);
            if (patientInfoResponseVo.getDateOfBirth() != null) {
                String ageStr = CountAgeUtil.getAgeStr(simpleDateFormat.format(patientInfoResponseVo.getDateOfBirth()));
                patientInfoResponseVo.setAgeStr(ageStr);
            }
        }
        return patientInfoResponseVo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateRegStatus(PatientInfoRequestVo requestVo) {
        int i = hisQueueMapper.updateRegStatus(requestVo);
        if (i == 0) {
            throw new CustomException("已被其他医生诊断");
        }
        // 就诊记录表 挂号状态字段 改成2-就诊状态
        requestVo.setRegistrationStatus(ServiceConstant.TWO_STRING);
        hisQueueMapper.updateClinicMaster(requestVo);
        return i;
    }

    @Override
    public List<DeptVo> selectDeptByEmpNo(String empNo, String hospitalCode) {
        return hisQueueMapper.selectDeptByEmpNo(empNo, hospitalCode);
    }

    @Override
    public WaitQueueResponseVo selectWaitQueue(WaitQueueRequestVo requestVo) {
        WaitQueueResponseVo result = new WaitQueueResponseVo();
        result.setList(hisQueueMapper.selectWaitQueue(requestVo));
        //候诊数量
        requestVo.setStatus(ServiceConstant.ONE_STRING);
        result.setWaitPatientNum(hisQueueMapper.selectCountByStatus(requestVo));
        //在诊数量
        requestVo.setStatus(ServiceConstant.THREE_STRING);
        result.setVisitPatientNum(hisQueueMapper.selectCountByStatus(requestVo));
        //已诊数量
        requestVo.setStatus(ServiceConstant.FOUR_STRING);
        result.setFinishPatientNum(hisQueueMapper.selectCountByStatus(requestVo));
        return result;
    }

    @Override
    public List<ClinicIndexVo> selectClinicIndex(ClinicIndexVo vo) {
        return hisQueueMapper.selectClinicIndex(vo);
    }

    @Override
    public List<ClinicMasterQueryVo> selectClinicMaster(String patientId, String hospitalCode) {
        return hisQueueMapper.selectClinicMaster(patientId, hospitalCode);
    }

    @Override
    public int finishVisit(PatientInfoRequestVo requestVo) {
        int i = hisQueueMapper.finishVisit(requestVo);
        if (i == 0) {
            throw new CustomException("该病人已完成就诊");
        }
        return i;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int cancelVisit(PatientInfoRequestVo requestVo) {
        int i = hisQueueMapper.cancelVisit(requestVo);
        if (i == 0) {
            throw new CustomException("病人已完成就诊，不能取消");
        }
        // 就诊记录表 挂号状态字段 改成1-已确认(已取号)状态
        requestVo.setRegistrationStatus(ServiceConstant.ONE_STRING);
        hisQueueMapper.updateClinicMaster(requestVo);
        return i;
    }

    @Override
    public boolean checkCancelVisit(PatientInfoRequestVo requestVo) {
        OutpWaitQueue outpWaitQueue = hisQueueMapper.selectCancelVisit(requestVo);
        if (outpWaitQueue != null && ServiceConstant.FOUR_STRING.equals(outpWaitQueue.getState())) {
            throw new CustomException("病人已完成就诊，不能取消");
        }
        if (outpWaitQueue != null && ServiceConstant.FIVE_STRING.equals(outpWaitQueue.getState())) {
            throw new CustomException("病人已经过诊，不能取消");
        }
        return true;
    }

    @Override
    public List<ClinicIndexVo> selectClinicType(ClinicIndexVo vo) {
        if (StringUtils.isEmpty(vo.getClinicDept())) {
            throw new CustomException("请选择科室");
        }
        return hisQueueMapper.selectClinicType(vo);
    }

    @Override
    public WaitQueueResponseVo selectQueueByClinicType(WaitQueueRequestVo requestVo, HttpServletRequest request) {
        if (CollectionUtils.isEmpty(requestVo.getClinicLabelList())) {
            throw new CustomException("号别数组不能为空");
        }
        //查询密级过滤数组
        AppBaseParam appBaseParam = new AppBaseParam();
        appBaseParam.setKeyName(AppBaseParamEnum.SECRET_LEVEL.getCode());
        List<AppBaseParam> appBaseParams = appBaseParamService.selectList(appBaseParam);
        if (!CollectionUtils.isEmpty(appBaseParams)) {
            List<String> list = appBaseParams.stream().map(AppBaseParam::getValueName).collect(Collectors.toList());
            requestVo.setSecretLevelList(list);
        }
        //根据页面展示范围，设置查询开始时间和结束时间
        if (requestVo.getDays() == null || requestVo.getDays() == 0 || requestVo.getDays() == 1) {
            requestVo.setStartTime(requestVo.getVisitDate());
        } else {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(requestVo.getVisitDate());
            calendar.add(Calendar.DATE, -(requestVo.getDays() - 1));
            Date startTime = calendar.getTime();
            requestVo.setStartTime(startTime);
        }
        requestVo.setEndTime(requestVo.getVisitDate());
        WaitQueueResponseVo result = new WaitQueueResponseVo();
        result.setList(hisQueueMapper.selectQueueByClinicType(requestVo));
        //候诊数量
        requestVo.setStatus(ServiceConstant.ONE_STRING);
        result.setWaitPatientNum(hisQueueMapper.selectCountByClinicType(requestVo));
        //在诊数量
        requestVo.setStatus(ServiceConstant.THREE_STRING);
        result.setVisitPatientNum(hisQueueMapper.selectCountByClinicType(requestVo));
        //已诊数量
        requestVo.setStatus(ServiceConstant.FOUR_STRING);
        result.setFinishPatientNum(hisQueueMapper.selectCountByClinicType(requestVo));
        //查询就诊队列展示天数配置
        result.setDaysList(selectAppBaseParamDays(request));
        return result;
    }

    private List<AppBaseParam> selectAppBaseParamDays(HttpServletRequest request) {
        //获取当前机构代码
        LoginUserDTO loginUserDTO = tokenService.getLoginUserDTO(tokenService.getToken(request));
        String hospitalCode = "";
        if (loginUserDTO != null && loginUserDTO.getSysSysuserVo() != null) {
            hospitalCode = loginUserDTO.getSysSysuserVo().getHospitalCode();
        }
        //查询就诊队列展示天数，先查机构，如果机构没有，再查全局
        AppBaseParam searchDays = new AppBaseParam();
        searchDays.setGroupName(ServiceConstant.QUEUE_QUERY_DAYS);
        searchDays.setType(ServiceConstant.GLOBAL_CONFIG_ORGAN);
        searchDays.setTypeValue(hospitalCode);
        List<AppBaseParam> searchDaysResult = appBaseParamService.selectList(searchDays);
        if (CollectionUtils.isEmpty(searchDaysResult)) {
            searchDays.setType(ServiceConstant.GLOBAL_CONFIG_ALL);
            searchDays.setTypeValue(null);
            searchDaysResult = appBaseParamService.selectList(searchDays);
            if (CollectionUtils.isEmpty(searchDaysResult)) {
                //如果没有配置，造一条数据
                searchDaysResult = new ArrayList<>();
                AppBaseParam one = new AppBaseParam();
                one.setKeyName("当天");
                one.setValueName("1");
                searchDaysResult.add(one);
            }
        }
        //按照valueName排序
        searchDaysResult.sort((o1, o2) -> {
            if (Integer.parseInt(o1.getValueName()) == Integer.parseInt(o2.getValueName())) {
                return 1;
            } else {
                return new BigDecimal(o1.getValueName()).compareTo(new BigDecimal(o2.getValueName()));
            }
        });
        return searchDaysResult;
    }
}
